package com.mec.ServerCluser.core;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;

public abstract class Communication implements Runnable {
	private boolean goon;
	private Socket socket;
	private DataInputStream dis;
	private DataOutputStream dos;
	private boolean isListenning;
	private static int count;
	private Object sign;
	
	public Communication(Socket socket) {
		sign = new Object();
		this.socket = socket;
		try {
			dis = new DataInputStream(this.socket.getInputStream());
			dos = new DataOutputStream(this.socket.getOutputStream());
			goon = true;
			isListenning = false;
			
			new Thread(this, "MEC Communication " + ++count).start();
			if (isListenning == false) {
				synchronized (sign) {
					try {
						sign.wait();
					} catch (InterruptedException e) {
					}
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	protected void send(NetMessage netMessage) {
		try {
			dos.writeUTF(netMessage.toString());
		} catch (IOException e) {
			peerAbnormalDrop();
			stop();
		}
	}
	
	protected abstract void dealNetMessage(NetMessage message);
	protected abstract void peerAbnormalDrop();
	
	@Override
	public void run() {
		isListenning = true;
		String message = null;
		synchronized (sign) {
			sign.notify();
		}
		
		while (goon) {
			try {
				message = dis.readUTF();
				dealNetMessage(new NetMessage(message));
			} catch (IOException e) {
				if (goon == true) {
					peerAbnormalDrop();
					goon = false;
				}
			}
		}
		stop();
	}

	protected void stop() {
		goon = false;
		try {
			if (dis != null) {
				dis.close();
			}
		} catch (IOException e) {
		} finally {
			dis = null;
		}
		try {
			if (dos != null) {
				dos.close();
			}
		} catch (IOException e) {
		} finally {
			dos = null;
		}
		try {
			if (socket != null && !socket.isClosed()) {
				socket.close();
			}
		} catch (IOException e) {
		} finally {
			socket = null;
		}
	}
	
}
